//
//  IAPManager.m
//  ImGuider
//
//  Created by llt on 2017/6/2.
//  Copyright © 2017年 imguider. All rights reserved.
//

#import "IAPManager.h"
#import "PayDAO.h"

@interface IAPManager () <SKPaymentTransactionObserver, SKProductsRequestDelegate>

@property (nonatomic, copy) NSString *orderid;

@property (nonatomic, copy) void (^ resultBlock) (NSString *result, NSError *error);

@property (nonatomic, strong) NSTimer *timer;

@property (nonatomic, strong) NSOperationQueue *opQueue;
@property (nonatomic, strong) dispatch_semaphore_t semaphore;

@end

@implementation IAPManager

+ (instancetype)sharedManager {
    
    static IAPManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [IAPManager new];
    });
    
    return manager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _semaphore = dispatch_semaphore_create(1);
        _opQueue = [[NSOperationQueue alloc] init];
        _opQueue.maxConcurrentOperationCount = 1;
    }
    return self;
}

- (void)startManager { //开启监听
    
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
    
    [self.opQueue addOperationWithBlock:^{
        
        [self checkIAPFiles];
    }];
    self.timer = [NSTimer timerWithTimeInterval:300 target:self selector:@selector(reverifyTimer) userInfo:nil repeats:YES];
    
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (void)checkIAPFiles {
    
    NSArray *watingVerifyArray = [PayDAO getAllOrderWithState:PayStatePaySuccessWatingVerify];
    
    for (PayModel *model in watingVerifyArray) {
        
        [self.opQueue addOperationWithBlock:^{
            
            dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
            [self verifyOrderWithPayModel:model];
        }];
    }
}

- (void)reverifyTimer {
    
    NSArray *reverifyArray = [PayDAO getAllOrderWithState:PayStatePaySuccessVerifyFaild];
    
    for (PayModel *model in reverifyArray) {
        
        [self.opQueue addOperationWithBlock:^{
            
            dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
            [self verifyOrderWithPayModel:model];
        }];
    }
}

- (void)stopManager{
    
    [self.opQueue addOperationWithBlock:^{
        
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }];
    [self.timer invalidate];
    self.timer = nil;
}


- (void)paymentID:(NSString *)paymentid couponid:(NSString *)couponid ordernumber:ordernumber
         andBlock:(void (^)(NSString *result, NSError *error))block {
    
    [self.opQueue addOperationWithBlock:^{
        
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        
        self.resultBlock = block;
        
        [NetAPIManager getPaymentinfoWithPaymentID:paymentid couponid:couponid ordernumber:ordernumber payType:PayTypeIAP merchType:MerchTypeLine andBlock:^(id result, NSError *error) {
            
            if (error) {
                if (self.resultBlock) {
                    self.resultBlock(nil,error);
                }
                
                dispatch_semaphore_signal(self.semaphore);
                return;
            }
            
            NSString *orderid = result[@"orderid"];
            
            id payInfo = result[@"notorderid"];
            
            PayModel *model = [PayModel new];
            model.orderid = orderid;
            model.payinfo = payInfo;
            model.lineid = paymentid;
            
            model.createtime = [NSDate date];
            
            self.orderid = orderid;
            
            if ([payInfo isEqualToString:@"free"]) {
                
                [self verifyOrderWithPayModel:model];
                return;
            }
            [PayDAO insertPayModel:model];
            
            [self requestProductWithId:payInfo];
        }];
        
    }];
}
#pragma mark 查询
- (void)requestProductWithId:(NSString *)productId {
    
    if ([SKPaymentQueue canMakePayments]) { //用户允许app内购
        
        if (productId.length) {
            
            IGLog(@"%@商品正在请求中",productId);
            
            NSArray *product = [[NSArray alloc] initWithObjects:productId, nil];
            
            NSSet *set = [NSSet setWithArray:product];
            
            SKProductsRequest *productRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
            
            productRequest.delegate = self;
            
            [productRequest start];
            
        } else {
            
            IGLog(@"商品为空");
            
            [self filedWithErrorCode:PAY_FILEDCOED_EMPTYGOODS error:nil];
        }
        
    } else { //没有权限
        
        [self filedWithErrorCode:PAY_FILEDCOED_NORIGHT error:nil];
    }
}

#pragma mark SKProductsRequestDelegate 查询成功后的回调
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    NSArray *products = response.products;
    
    if (products.count == 0) {
        
        IGLog(@"无法获取商品信息，请重试");
        
        [self filedWithErrorCode:PAY_FILEDCOED_CANNOTGETINFORMATION error:nil];
        
    } else {
        //发起购买请求
        
        SKProduct *product = [products firstObject];
        
        [AppManager sharedManager].currentCountryCode = [product.priceLocale objectForKey:NSLocaleCountryCode];;
        
        PayModel *model = [PayDAO getPayModelWithOrderid:self.orderid];
        
        if (!model) {
            
            [self filedWithErrorCode:PAY_FILEDCOED_CANNOTGETINFORMATION error:nil];
            return;
        }
        
        model.currency = [product.priceLocale objectForKey:NSLocaleCurrencyCode];;
        [PayDAO insertPayModel:model];
        
        SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
        
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
}

#pragma mark SKProductsRequestDelegate 查询失败后的回调
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    
    [self filedWithErrorCode:PAY_FILEDCOED_APPLECODE error:[error localizedDescription]];
}

#pragma Mark 购买操作后的回调
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions {
    
    for (SKPaymentTransaction *transaction in transactions) {
        
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing://正在交易
            {
                
                
                break;
                
            }
                
            case SKPaymentTransactionStatePurchased://交易完成
            {
                NSString *receipt = [self getReceipt]; //获取交易成功后的购买凭证
                
                PayModel *model = nil;
                
                if (self.orderid) {
                    model = [PayDAO getPayModelWithOrderid:self.orderid];
                    
                    if (!model) {
                        model = [PayModel new];
                        model.orderid = self.orderid;
                    }
                }
                
                if (!model) {
                    model = [PayDAO getPayModelWithTransid:transaction.transactionIdentifier];
                }
                
                if (!model) {
                    model = [[PayDAO getAllOrderWithState:PayStateWatingPay] firstObject];
                    
                    if (model) {
                        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
                    }
                }
                
                model.payinfo = receipt;
                model.transid = transaction.transactionIdentifier;
                model.payState = PayStatePaySuccessWatingVerify;
                
                if (model) {
                    [PayDAO insertPayModel:model];
                    
                    [self verifyOrderWithPayModel:model];
                }
                
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                
                break;
            }
                
            case SKPaymentTransactionStateFailed://交易失败
            {
                [self failedTransaction:transaction];
                
                break;
            }
                
            case SKPaymentTransactionStateRestored://已经购买过该商品
            {
                [self restoreTransaction:transaction];
                
                break;
            }
                
            default:
                
                break;
        }
    }
}


- (void)failedTransaction:(SKPaymentTransaction *)transaction {
    
    IGLog(@"transaction.error.code = %ld", transaction.error.code);
    
    if(transaction.error.code != SKErrorPaymentCancelled) {
        
        [self filedWithErrorCode:PAY_FILEDCOED_BUYFILED error:[IGUtils tipFromError:transaction.error]];
        
        
    } else {
        
        [self filedWithErrorCode:PAY_FILEDCOED_USERCANCEL error:[IGUtils tipFromError:transaction.error]];
    }
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
}


- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
    
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    
    dispatch_semaphore_signal(self.semaphore);
}

#pragma mark 获取交易成功后的购买凭证

- (NSString *)getReceipt {
    
    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptUrl];
    
    return [receiptData base64EncodedStringWithOptions:0];
}

#pragma mark 错误信息反馈
- (void)filedWithErrorCode:(NSInteger)code error:(NSString *)error {
    
    //    if (self.resultBlock) self.resultBlock(nil,error);
    
    NSString *errorMsg = @"";
    switch (code) {
        case PAY_FILEDCOED_APPLECODE: // 苹果返回错误信息
        {
            errorMsg = error;
            break;
        }
            
        case PAY_FILEDCOED_NORIGHT: // 用户禁止应用内付费购买
        {
            errorMsg = MYLocalizedString(@"PAYORDER_FAILED_FORBID", nil);
            break;
        }
            
        case PAY_FILEDCOED_EMPTYGOODS: // 商品为空
        {
            errorMsg = MYLocalizedString(@"PAYORDER_FAILED_NULL", nil);
            break;
        }
            
        case PAY_FILEDCOED_USERCANCEL:// 用户取消交易
        {
            errorMsg = MYLocalizedString(@"PAYORDER_FAILED_CANCEL", nil);
            break;
        }
            
        case PAY_FILEDCOED_CANNOTGETINFORMATION: // 无法获取产品信息，请重试
        {
            errorMsg = MYLocalizedString(@"PAYORDER_FAILED_NOTAVAILABLE", nil);
            break;
        }
            
        case PAY_FILEDCOED_BUYFILED: // 购买失败，请重试
        {
            errorMsg = error.length > 0 ? error : MYLocalizedString(@"PAYORDER_FAILED_FAILD", nil);
            break;
        }
            
        default:
            break;
    }
    NSError *errorObj = [NSError errorWithDomain:[AppManager sharedManager].baseURLStr code:code userInfo:@{@"msg":errorMsg}];
    if (self.resultBlock) self.resultBlock(nil,errorObj);
    dispatch_semaphore_signal(self.semaphore);
    
    [PayDAO deletePayModelWithOrderid:self.orderid];
}

#pragma 验证结果
- (void)verifyOrderWithPayModel:(PayModel *)model {
    
    if (model.orderid == 0 || model.payinfo == 0) {
        
        if (self.resultBlock) {
            self.resultBlock(nil, [NSError errorWithDomain:[AppManager sharedManager].baseURLStr code:-1 userInfo:@{@"errmsg":@"订单丢失"}]);
        }
        
        dispatch_semaphore_signal(self.semaphore);
        return;
    }
    @weakify(self);
    [NetAPIManager verifyPaymentOrderID:model.orderid notorderid:model.payinfo currency:model.currency payType:PayTypeIAP andBlock:^(id result, NSError *error) {
        @strongify(self);
        
        if (error) {
            
            if (self.resultBlock) {
                @weakify(self);
                [IGAlertView alertWithTitle:@"" message:[IGUtils tipFromError:error] cancelButtonTitle:MYLocalizedString(@"PUBLIC_CANCEL", nil) commitBtn:MYLocalizedString(@"PUBLIC_RETRY", nil) commit:^{
                    @strongify(self);
                    [self verifyOrderWithPayModel:model];
                    
                } cancel:^{
                    @strongify(self);
                    self.resultBlock(result,error);
                    dispatch_semaphore_signal(self.semaphore);
                    
                    model.payState = PayStatePaySuccessVerifyFaild;
                    [PayDAO insertPayModel:model];
                }];
                
                
            } else {
                
                dispatch_semaphore_signal(self.semaphore);
                model.payState = PayStatePaySuccessVerifyFaild;
                [PayDAO insertPayModel:model];
            }
            return;
        }
        
        dispatch_semaphore_signal(self.semaphore);
        [PayDAO deletePayModelWithOrderid:model.orderid];
        if (result[@"orderstatus"] && [result[@"orderstatus"] integerValue] != 1) {
            
            error = [NSError errorWithDomain:[AppManager sharedManager].baseURLStr code:PAY_FILEDCOED_SERVERERROR userInfo:@{@"errmsg":@"支付失败，详情请联系客服"}];
        }
        
        if (self.resultBlock) self.resultBlock(result,error);
    }];
}

@end

